﻿#pragma once

#include "Widgets/Widget.h"
#include "Font/StaticTextArranger.h"
#include "Widgets/Mouse/MouseWidget.h"
#include "Widgets/Keyboard/KeyboardWidget.h"
#include "EditableTextWidget.m.h"

class RFont;

RENUM(ExportMacro="WHENGINE_API")
enum class ETextEditStopReason
{
    LostFocus, 
    Accept, //imply accept text
    Cancel, //user might pressed Escape, imply cancel edit and restore text
};


//单行文本编辑控件
RCLASS()
class WHENGINE_API REditableTextWidget : public RWidget
{
    ROBJECT
public:
    REditableTextWidget();

    //当用户不编辑时显示的文本
    //如果用户正在编辑，这个属性会被忽略
    //如果用户完成了编辑，那么会立即显示这个文本
    //如果希望在用户完成编辑后显示编辑后的文本，可以将UpdateTextOnAccepted设置为true
    RFIELD()
    TWidgetAttribute<CString> Text;

    //当用户完成编辑后，是否将Text属性设置为编辑后的文本
    RFIELD()
    TWidgetAttribute<bool> UpdateTextOnAccepted=false;

    //当用户失去焦点时，是否将Text属性设置为编辑后的文本
    RFIELD()
    TWidgetAttribute<bool> UpdateTextOnLostFocus=false;

    //当用户完成/取消/中断编辑时触发
    RFIELD()
    TScriptDelegate<void(ETextEditStopReason,const CString& )> OnEditStopped;
    
    //仅当用户完成编辑时触发，不会因为失去焦点或者按下esc键而触发
    RFIELD()
    TScriptDelegate<void(const CString&  )> OnTextAccepted;

    RFIELD()
    TScriptDelegate<void(const CString& /*新的字符串*/ )> OnTextUpdated;

    //获取正在显示的文本
    RFUNCTION()
    CString GetDisplayingText();

    RFIELD()
    TWidgetAttribute<TSharedObjectPtr<RFont>> Font;

    RFIELD()
    TWidgetAttribute<int64_t> FontSize=16;

    RFIELD()
    TWidgetAttribute<SColor> Color=SColor::White;

    RFIELD()
    TWidgetAttribute<ETextHorizontalAlignment>HorizontalAlignment= ETextHorizontalAlignment::Left;
    
    RFIELD()
    TWidgetAttribute<ETextVerticalAlignment> VerticalAlignment=ETextVerticalAlignment::Top;

    RFIELD()
    TWidgetAttribute<float> CursorWidth=2;

    RFIELD()
    TWidgetAttribute<SColor> CursorColor=SColor::White;

    void StartEdit();

    void CancelEdit();

    bool IsEditing() ;
protected:
    void PaintSelf(uint16_t& InZOrder,const SRect& InClipArea) override;
    TWeakObjectPtr<RMouseWidget> Mouse;
    TWeakObjectPtr<RKeyboardWidget> Keyboard;

    //在编辑时显示的文本
    CString EditingDisplayText;

    bool bIsEditing=false;

    virtual void CalculatePresentPositionAndSize() override;
    void ArrangeGlyphs();


    CStaticTextArranger TextArranger;

    void OnFocused() ;
    void OnUnfocused() ;
    bool ProcessTextInput(const STextInputEvent& BoardkeyEvent) ;
    bool ProcessKeyInput(const SKeyboardEvent& BoardkeyEvent) ;

    void ForceShowCursor();
    void HideCursor();

    //在光标之前的字符索引，如果光标在开头，就是-1
    int64_t CursorPosition=-1; 
    //is cursor visible
    bool bShowCursor=false;
    //time is auto increase, if > CursorBlinkTime, will reset to 0
    //and toggle bShowCursor
    float CursorTime=0; 
    const float CursorBlinkTime=0.5f;

    TSharedObjectPtr<RFont> GetRenderingFont();

    virtual void Tick(float DeltaSeconds) override;
};